/** @file               sw_type.h
 *  @copyright          Copyright (C) 2006-2026 flyfish (tenggui_fu@126.com)
 *  @brief              This file is part of the swallow library
 *  @author             $Author: flyfish $
 *  @version            $Rev: 401 $
 *  @date               $Date: 2016-12-27 00:02:40 +0800 (周二, 27 12月 2016) $
 */
#ifndef __SW_TYPE_H__
#define __SW_TYPE_H__

#ifdef WIN32
    #ifdef SW_EXPORTS
        #define SW_API __declspec(dllexport)
    #else
        #define SW_API extern
    #endif
#else
    #define SW_API extern
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
#define SW_VOID             void
#else
typedef void                SW_VOID;
#endif

typedef signed char         SW_INT8;
typedef unsigned char       SW_UINT8;
typedef char                SW_CHAR;
typedef unsigned char       SW_UCHAR;
typedef signed short        SW_INT16;
typedef unsigned short      SW_UINT16;
typedef signed int          SW_INT;
typedef unsigned int        SW_UINT;
typedef signed int          SW_INT32;
typedef unsigned int        SW_UINT32;

#ifdef WIN32
typedef signed __int64      SW_INT64;
typedef unsigned __int64    SW_UINT64;
#else
typedef signed long long    SW_INT64;
typedef unsigned long long  SW_UINT64;
#endif

typedef signed long         SW_LONG;
typedef unsigned long       SW_ULONG;
typedef double              SW_DOUBLE;
typedef float               SW_FLOAT;

#define SW_INVALID_INT8     (SW_INT8)(-1)
#define SW_INVALID_UINT8    (SW_UINT8)(-1)
#define SW_INVALID_INT16    (SW_INT16)(-1)
#define SW_INVALID_UINT16   (SW_UINT16)(-1)
#define SW_INVALID_INT      (SW_INT)(-1)
#define SW_INVALID_UINT     (SW_UINT)(-1)
#define SW_INVALID_INT32    (SW_INT32)(-1)
#define SW_INVALID_UINT32   (SW_UINT32)(-1)
#define SW_INVALID_INT64    (SW_INT32)(-1)
#define SW_INVALID_UINT64   (SW_UINT32)(-1)
#define SW_INVALID_DOUBLE   (SW_DOUBLE)(-1)
#define SW_INVALID_FLOAT    (SW_FLOAT)(-1)
#define SW_INVALID_ENUM     (SW_INT32)(-1)
#define SW_INVALID_PROC     NULL

#define SW_INT8_MAX         INT8_MAX
#define SW_INT8_MIN         INT8_MIN
#define SW_UINT8_MAX        UINT8_MAX
#define SW_INT16_MAX        INT16_MAX
#define SW_INT16_MIN        INT16_MIN
#define SW_UINT16_MAX       UINT16_MAX
#define SW_INT_MAX          INT_MAX
#define SW_INT_MIN          INT_MIN
#define SW_UINT_MAX         UINT_MAX
#define SW_INT32_MAX        INT32_MAX
#define SW_INT32_MIN        INT32_MIN
#define SW_UINT32_MAX       UINT32_MAX
#define SW_INT64_MAX        INT64_MAX
#define SW_INT64_MIN        INT64_MIN
#define SW_UINT64_MAX       UINT64_MAX
#define SW_RAND_MAX         RAND_MAX

#define SW_TIMEOUT_FOREVER  UINT32_MAX
#define SW_TIMEOUT_NONE     0

typedef enum _SW_DATA_TYPE
{
    SW_DT_VOID,
    SW_DT_INT8,
    SW_DT_UINT8,
    SW_DT_CHAR,
    SW_DT_UCHAR,
    SW_DT_INT16,
    SW_DT_UINT16,
    SW_DT_INT,
    SW_DT_UINT,
    SW_DT_INT32,
    SW_DT_UINT32,
    SW_DT_INT64,
    SW_DT_UINT64,
    SW_DT_BOOL,
    SW_DT_POINTER,
    SW_DT_STRING,
    SW_DT_FLOAT,
    SW_DT_DOUBLE,
    SW_DT_FILENAME
}SW_DATA_TYPE;

typedef union _SW_FLOAT_MEM
{
    SW_UINT32 data;
    SW_FLOAT value;
}SW_FLOAT_MEM;

typedef union _SW_DOUBLE_MEM
{
    SW_UINT64 data;
    SW_DOUBLE value;
}SW_DOUBLE_MEM;

typedef enum _SW_DATA_BASE
{
    SW_DB_HEX,
    SW_DB_DEC,
    SW_DB_OCT,
    SW_DB_BIN
}SW_DATA_BASE;

typedef enum _SW_BOOL
{
    SW_B_FALSE,
    SW_B_TRUE
}SW_BOOL;

typedef enum _SW_PIN_LEVEL
{
    SW_PL_LOW,
    SW_PL_HIGH,
    SW_PL_HIGHRES,
    SW_PL_INVALID = -1
}SW_PIN_LEVEL;

typedef enum _SW_PIN_DIRECTION
{
    SW_PD_OUTPUT,
    SW_PD_INPUT
}SW_PIN_DIRECTION;

typedef enum _SW_RET
{
    SW_R_SUCCESS = 0,
    SW_R_FAILURE = -1
}SW_RET;

typedef enum _SW_CMP
{
    SW_C_EQ,
    SW_C_LT,
    SW_C_GT,
    SW_C_INVALID = -1
}SW_CMP;

typedef enum _SW_H_ALIGN
{
    SW_HA_LEFT,
    SW_HA_RIGHT,
    SW_HA_MID,
    SW_HA_INVALID = -1
}SW_H_ALIGN;

typedef enum _SW_V_ALIGN
{
    SW_VA_TOP,
    SW_VA_BOT,
    SW_VA_MID,
    SW_VA_INVALID = -1
}SW_V_ALIGN;

#ifdef WIN32
#undef SW_MAX
#endif

#define SW_DIM(x)                               (sizeof(x) / sizeof(x[0]))
#define SW_MIN(x, y)                            (((x) <= (y)) ? (x) : (y))
#define SW_MAX(x, y)                            (((x) >= (y)) ? (x) : (y))
#define SW_MID(x, v, y)                         (SW_MIN(SW_MAX((x), (v)), (y)))
#define SW_DIV(x, y)                            (((x) + (y) / 2) / (y))
#define SW_MAP(sx, sv, sy, dx, dy)              (SW_MID((dx), (SW_DIV((((sv) - (sx)) * ((dy) - (dx))), ((sy) - (sx))) + (dx)), (dy)))
#define SW_MAP2(sx, sv, sy, dx, dy)             (((dx) <= (dy)) ? (SW_MAP((sx), (sv), (sy), (dx), (dy))) : ((dx) + (dy) - SW_MAP((sx), (sv), (sy), (dy), (dx))))
#define SW_DIVF(x, y)                           ((SW_DOUBLE)(x) / (SW_DOUBLE)(y))
#define SW_MAPF(sx, sv, sy, dx, dy)             (SW_MID((SW_DOUBLE)(dx), (SW_DIVF((((SW_DOUBLE)(sv) - (SW_DOUBLE)(sx)) * ((SW_DOUBLE)(dy) - (SW_DOUBLE)(dx))), ((SW_DOUBLE)(sy) - (SW_DOUBLE)(sx))) + (SW_DOUBLE)(dx)), (SW_DOUBLE)(dy)))
#define SW_MAPF2(sx, sv, sy, dx, dy)            (((dx) <= (dy)) ? (SW_MAPF((sx), (sv), (sy), (dx), (dy))) : ((dx) + (dy) - SW_MAPF((sx), (sv), (sy), (dy), (dx))))
#define SW_TMAP(sv, sx, sm, sy, dx, dm, dy)     (((sv) <= (sm)) ? SW_MAP2((sx), (sv), (sm), (dx), (dm)) : SW_MAP2((sm), (sv), (sy), (dm), (dy)))
#define SW_TMAPF(sv, sx, sm, sy, dx, dm, dy)    (((sv) <= (sm)) ? SW_MAPF2((sx), (sv), (sm), (dx), (dm)) : SW_MAPF2((sm), (sv), (sy), (dm), (dy)))
#define SW_ALIGN_DOWN(x, align)                 ((x) / (align) * (align))
#define SW_ALIGN_UP(x, align)                   (((x) + (align) - 1) / (align) * (align))
#define SW_DIFF(x, y)                           (((x) >= (y)) ? ((x) - (y)) : ((y) - (x)))
#define SW_TOS(x)                               #x
#define SW_OFFSETOF(type, member)               ((SW_UINT32)&((type *)0)->member)
#define SW_SWAP(x, y, type)                     do {type tmp; tmp = x; x = y; y = tmp;} while(0)
#define SW_ABS(x)                               ((x) >= 0 ? (x) : -(x))
#define SW_DIV_0_TO_1(x)                        ((0 == (x)) ? 1 : (x))
#define SW_USUB(x, y)                           (((x) >= (y)) ? ((x) - (y)) : 0)
#define SW_BITMASK(x)                           (1 << (x))

#define SW_FIRST_ITEM_STRUCT(gtbl, vtbl, item) \
do \
{ \
    SW_UINT32 i, j; \
    for (i=0; i<SW_DIM(gtbl); i++) \
    { \
        vtbl[i] = &gtbl[i]; \
        if (gtbl[i].item == item) \
        { \
            for (j=i; j>0; j--) \
            { \
                vtbl[j] = vtbl[j-1]; \
            } \
            vtbl[0] = &gtbl[i]; \
        } \
    } \
} while(0)

#define SW_FIRST_ITEM_ARRAY(gtbl, vtbl, item) \
do \
{ \
    SW_UINT32 i, j; \
    for (i=0; i<SW_DIM(gtbl); i++) \
    { \
        vtbl[i] = gtbl[i]; \
        if (gtbl[i] == item) \
        { \
            for (j=i; j>0; j--) \
            { \
                vtbl[j] = vtbl[j-1]; \
            } \
            vtbl[0] = gtbl[i]; \
        } \
    } \
} while(0)

#define SW_LIMIT_TYPEDEF(t) \
typedef struct _SW_LIMIT_##t \
{ \
	SW_##t min; \
	SW_##t max; \
	SW_##t typical; \
}SW_LIMIT_##t
SW_LIMIT_TYPEDEF(INT8);  
SW_LIMIT_TYPEDEF(UINT8); 
SW_LIMIT_TYPEDEF(CHAR);  
SW_LIMIT_TYPEDEF(UCHAR); 
SW_LIMIT_TYPEDEF(INT16); 
SW_LIMIT_TYPEDEF(UINT16);
SW_LIMIT_TYPEDEF(INT);   
SW_LIMIT_TYPEDEF(UINT);  
SW_LIMIT_TYPEDEF(INT32); 
SW_LIMIT_TYPEDEF(UINT32);
SW_LIMIT_TYPEDEF(INT64); 
SW_LIMIT_TYPEDEF(UINT64);
SW_LIMIT_TYPEDEF(LONG);  
SW_LIMIT_TYPEDEF(ULONG); 
SW_LIMIT_TYPEDEF(DOUBLE);
SW_LIMIT_TYPEDEF(FLOAT);

#define SW_RANGE_TYPEDEF(t) \
typedef struct _SW_RANGE_##t \
{ \
	SW_##t min; \
	SW_##t max; \
}SW_RANGE_##t
SW_RANGE_TYPEDEF(INT8);  
SW_RANGE_TYPEDEF(UINT8); 
SW_RANGE_TYPEDEF(CHAR);  
SW_RANGE_TYPEDEF(UCHAR); 
SW_RANGE_TYPEDEF(INT16); 
SW_RANGE_TYPEDEF(UINT16);
SW_RANGE_TYPEDEF(INT);   
SW_RANGE_TYPEDEF(UINT);  
SW_RANGE_TYPEDEF(INT32); 
SW_RANGE_TYPEDEF(UINT32);
SW_RANGE_TYPEDEF(INT64); 
SW_RANGE_TYPEDEF(UINT64);
SW_RANGE_TYPEDEF(LONG);  
SW_RANGE_TYPEDEF(ULONG); 
SW_RANGE_TYPEDEF(DOUBLE);
SW_RANGE_TYPEDEF(FLOAT);

#define SW_POINT_TYPEDEF(t) \
typedef struct _SW_POINT_##t \
{ \
	SW_##t x; \
	SW_##t y; \
}SW_POINT_##t
SW_POINT_TYPEDEF(INT8);  
SW_POINT_TYPEDEF(UINT8); 
SW_POINT_TYPEDEF(CHAR);  
SW_POINT_TYPEDEF(UCHAR); 
SW_POINT_TYPEDEF(INT16); 
SW_POINT_TYPEDEF(UINT16);
SW_POINT_TYPEDEF(INT);   
SW_POINT_TYPEDEF(UINT);  
SW_POINT_TYPEDEF(INT32); 
SW_POINT_TYPEDEF(UINT32);
SW_POINT_TYPEDEF(INT64); 
SW_POINT_TYPEDEF(UINT64);
SW_POINT_TYPEDEF(LONG);  
SW_POINT_TYPEDEF(ULONG); 
SW_POINT_TYPEDEF(DOUBLE);
SW_POINT_TYPEDEF(FLOAT);

#define SW_POS_TYPEDEF(t) \
typedef struct _SW_POS_##t \
{ \
	SW_##t x; \
	SW_##t y; \
}SW_POS_##t
SW_POS_TYPEDEF(INT8);  
SW_POS_TYPEDEF(UINT8); 
SW_POS_TYPEDEF(CHAR);  
SW_POS_TYPEDEF(UCHAR); 
SW_POS_TYPEDEF(INT16); 
SW_POS_TYPEDEF(UINT16);
SW_POS_TYPEDEF(INT);   
SW_POS_TYPEDEF(UINT);  
SW_POS_TYPEDEF(INT32); 
SW_POS_TYPEDEF(UINT32);
SW_POS_TYPEDEF(INT64); 
SW_POS_TYPEDEF(UINT64);
SW_POS_TYPEDEF(LONG);  
SW_POS_TYPEDEF(ULONG); 
SW_POS_TYPEDEF(DOUBLE);
SW_POS_TYPEDEF(FLOAT);

#define SW_FLOAT_TYPEDEF(t) \
typedef struct _SW_FLOAT_##t \
{ \
	SW_##t integer; \
	SW_##t decimal; \
}SW_FLOAT_##t
SW_FLOAT_TYPEDEF(INT8);  
SW_FLOAT_TYPEDEF(UINT8); 
SW_FLOAT_TYPEDEF(CHAR);  
SW_FLOAT_TYPEDEF(UCHAR); 
SW_FLOAT_TYPEDEF(INT16); 
SW_FLOAT_TYPEDEF(UINT16);
SW_FLOAT_TYPEDEF(INT);   
SW_FLOAT_TYPEDEF(UINT);  
SW_FLOAT_TYPEDEF(INT32); 
SW_FLOAT_TYPEDEF(UINT32);
SW_FLOAT_TYPEDEF(INT64); 
SW_FLOAT_TYPEDEF(UINT64);
SW_FLOAT_TYPEDEF(LONG);  
SW_FLOAT_TYPEDEF(ULONG); 

#define SW_SIZE_TYPEDEF(t) \
typedef struct _SW_SIZE_##t \
{ \
	SW_##t width; \
	SW_##t height; \
}SW_SIZE_##t
SW_SIZE_TYPEDEF(INT8);  
SW_SIZE_TYPEDEF(UINT8); 
SW_SIZE_TYPEDEF(CHAR);  
SW_SIZE_TYPEDEF(UCHAR); 
SW_SIZE_TYPEDEF(INT16); 
SW_SIZE_TYPEDEF(UINT16);
SW_SIZE_TYPEDEF(INT);   
SW_SIZE_TYPEDEF(UINT);  
SW_SIZE_TYPEDEF(INT32); 
SW_SIZE_TYPEDEF(UINT32);
SW_SIZE_TYPEDEF(INT64); 
SW_SIZE_TYPEDEF(UINT64);
SW_SIZE_TYPEDEF(LONG);  
SW_SIZE_TYPEDEF(ULONG); 
SW_SIZE_TYPEDEF(DOUBLE);
SW_SIZE_TYPEDEF(FLOAT);

#define SW_RESOLUTION_TYPEDEF(t) \
typedef struct _SW_RESOLUTION_##t \
{ \
	SW_##t width; \
	SW_##t height; \
}SW_RESOLUTION_##t
SW_RESOLUTION_TYPEDEF(INT8);  
SW_RESOLUTION_TYPEDEF(UINT8); 
SW_RESOLUTION_TYPEDEF(CHAR);  
SW_RESOLUTION_TYPEDEF(UCHAR); 
SW_RESOLUTION_TYPEDEF(INT16); 
SW_RESOLUTION_TYPEDEF(UINT16);
SW_RESOLUTION_TYPEDEF(INT);   
SW_RESOLUTION_TYPEDEF(UINT);  
SW_RESOLUTION_TYPEDEF(INT32); 
SW_RESOLUTION_TYPEDEF(UINT32);
SW_RESOLUTION_TYPEDEF(INT64); 
SW_RESOLUTION_TYPEDEF(UINT64);
SW_RESOLUTION_TYPEDEF(LONG);  
SW_RESOLUTION_TYPEDEF(ULONG); 
SW_RESOLUTION_TYPEDEF(DOUBLE);
SW_RESOLUTION_TYPEDEF(FLOAT);

#define SW_RECT_TYPEDEF(t) \
typedef struct _SW_RECT_##t \
{ \
    SW_##t x; \
    SW_##t y; \
	SW_##t width; \
	SW_##t height; \
}SW_RECT_##t
SW_RECT_TYPEDEF(INT8);  
SW_RECT_TYPEDEF(UINT8); 
SW_RECT_TYPEDEF(CHAR);  
SW_RECT_TYPEDEF(UCHAR); 
SW_RECT_TYPEDEF(INT16); 
SW_RECT_TYPEDEF(UINT16);
SW_RECT_TYPEDEF(INT);   
SW_RECT_TYPEDEF(UINT);  
SW_RECT_TYPEDEF(INT32); 
SW_RECT_TYPEDEF(UINT32);
SW_RECT_TYPEDEF(INT64); 
SW_RECT_TYPEDEF(UINT64);
SW_RECT_TYPEDEF(LONG);  
SW_RECT_TYPEDEF(ULONG); 
SW_RECT_TYPEDEF(DOUBLE);
SW_RECT_TYPEDEF(FLOAT);

#define SW_GEOMETRY_TYPEDEF(t) \
typedef struct _SW_GEOMETRY_##t \
{ \
    SW_##t x; \
    SW_##t y; \
	SW_##t width; \
	SW_##t height; \
}SW_GEOMETRY_##t
SW_GEOMETRY_TYPEDEF(INT8);  
SW_GEOMETRY_TYPEDEF(UINT8); 
SW_GEOMETRY_TYPEDEF(CHAR);  
SW_GEOMETRY_TYPEDEF(UCHAR); 
SW_GEOMETRY_TYPEDEF(INT16); 
SW_GEOMETRY_TYPEDEF(UINT16);
SW_GEOMETRY_TYPEDEF(INT);   
SW_GEOMETRY_TYPEDEF(UINT);  
SW_GEOMETRY_TYPEDEF(INT32); 
SW_GEOMETRY_TYPEDEF(UINT32);
SW_GEOMETRY_TYPEDEF(INT64); 
SW_GEOMETRY_TYPEDEF(UINT64);
SW_GEOMETRY_TYPEDEF(LONG);  
SW_GEOMETRY_TYPEDEF(ULONG); 
SW_GEOMETRY_TYPEDEF(DOUBLE);
SW_GEOMETRY_TYPEDEF(FLOAT);

#define SW_FRACTION_TYPEDEF(t) \
typedef struct _SW_FRACTION_##t \
{ \
    SW_##t numerator; \
    SW_##t denominator; \
}SW_FRACTION_##t
SW_FRACTION_TYPEDEF(INT8);  
SW_FRACTION_TYPEDEF(UINT8); 
SW_FRACTION_TYPEDEF(CHAR);  
SW_FRACTION_TYPEDEF(UCHAR); 
SW_FRACTION_TYPEDEF(INT16); 
SW_FRACTION_TYPEDEF(UINT16);
SW_FRACTION_TYPEDEF(INT);   
SW_FRACTION_TYPEDEF(UINT);  
SW_FRACTION_TYPEDEF(INT32); 
SW_FRACTION_TYPEDEF(UINT32);
SW_FRACTION_TYPEDEF(INT64); 
SW_FRACTION_TYPEDEF(UINT64);
SW_FRACTION_TYPEDEF(LONG);  
SW_FRACTION_TYPEDEF(ULONG); 
SW_FRACTION_TYPEDEF(DOUBLE);
SW_FRACTION_TYPEDEF(FLOAT);

#define SW_LIMIT            SW_LIMIT_UINT32
#define SW_RANGE            SW_RANGE_UINT32
#define SW_POINT            SW_POINT_INT32
#define SW_RESOLUTION       SW_RESOLUTION_UINT32
#define SW_SIZE             SW_SIZE_UINT32
#define SW_POS              SW_POS_UINT32
#define SW_RECT             SW_RECT_UINT32
#define SW_GEOMETRY         SW_GEOMETRY_UINT32
#define SW_FRACTION         SW_FRACTION_UINT32

#define SW_S32_BIG_NUM  (~(1<<31))
#define SW_S16_BIG_NUM  (~(1<<15))

typedef SW_INT32 (*SW_CALLBACK)(SW_INT32 param);

#define SW_FOREVER              for (;;)

#if defined(WIN32) && !defined(__MINGW32__)
#define __SW_STR2__(x)      #x  
#define __SW_STR1__(x)      __SW_STR2__(x)  
#define __SW_LOC__          __FILE__ "("__SW_STR1__(__LINE__)") : warning: " 
#endif

#ifdef __cplusplus
}
#endif

#endif

